package pessoa;

import excecoes.CpfCnpjInvalidoException;

/**
 * Essa classe mantem os atributos e metodos comuns as classes Cliente e Fornecedor
 *
 * Obs: esta definida apenas a estrutura da classe, os metodos devem ser implementados
 * e suas assinaturas alteradas de acordo com a necessidade
 */
public class Pessoa {

	private String nome;
	private String telefone;
	private String email;
	private String endereco;


	/**
	 * Esse construtor recebe nome, telefone, email e endereco, e os atribui aos
	 * respectivos atributos na classe
	 * 
	 * @param nome
	 * @param telefone
	 * @param email
	 * @param endereco
	 */
	public Pessoa(String nome, String telefone, String email, String endereco) {

		this.nome = nome;
		this.telefone = telefone;
		this.email = email;
		this.endereco = endereco;

	}

	/**
	 * Esse metodo verifica se um numero de cpf e valido, ele e static pois
	 * precisa ser chamado antes mesmo q haja um objeto
	 * 
	 * @param String cpf: string contendo o cpf
	 * @return true se o cpf for valido
	 * @return false se o cpf for invalido
	 */

	public static boolean validaCpfCnpj(String cpfCnpj){


		/*
		 * O cliente pode ser uma pessoa fisica ou juridica, logo ele pode ter um cpf (11 digitos)
		 *  ou cnpj (14 digitos). Se o numero passado tiver uma quantidade de digitos diferente
		 *  de 11 e 14, entao ele e invalido
		 */
		if(cpfCnpj.length() != 11 && cpfCnpj.length() != 14){

			return false;

			/*
			 * Se o numero tiver 14 digitos, chama a funcao de validar cnpj
			 */
		}else if(cpfCnpj.length() == 14){

			return validaCnpj(cpfCnpj);

			/*
			 * Se o numero tiver 12 digitos, chama a funcao de validar cpf
			 */
		}else{

			return validaCpf(cpfCnpj);

		}

	}//validaCpfCnpj(String cpfCnpj)

	private static boolean validaCpf(String cpf){

		/*
		 * Limpa  qualquer caractere da string q nao seja numeros
		 * (vide Expressoes Regulares)
		 */
		cpf = cpf.replaceAll("[^0-9]", "");

		/*
		 * Se a string do cpf tiver menos q 11 digitos, ele e invalido
		 */
		if(cpf.length() < 11){

			return false;
		}

		if(primeiroDigitoCpf(cpf) == true && segundoDigitoCpf(cpf)==true){

			return true;

		}else{

			return false;

		}
	}//validaCpf(String cpf)

	/**
	 * Esse metodo verifica se um numero de cnpj e valido, ele e static pois
	 * precisa ser chamado antes mesmo q haja um objeto
	 * 
	 * @param String cnpj: String contendo o cnpj
	 * @return true se o cnpj for valido
	 * @return false se o cnpj for invalido
	 * 
	 */
	private static boolean validaCnpj(String cnpj){

		/*
		 * Limpa  qualquer caractere da string q nao seja numeros
		 * (vide Expressoes Regulares)
		 */
		cnpj = cnpj.replaceAll("[^0-9]","");

		/*
		 * Se a string do cnpj tiver menos q 11 digitos, ele e invalido
		 */
		if(cnpj.length() < 14){

			return false;
		}

		if(primeiroDigitoCnpj(cnpj) == true
				&& segundoDigitoCnpj(cnpj)==true){

			return true;

		}else{

			return false;

		}
	}//validaCnpj(String cnpj)


	/**
	 * 
	 * Esse metodo e usado pela funcao validaCpf para verificar
	 * se um cpf e valido, o metodo e static pois e usado pelo 
	 * metodo validarCpf()
	 * 
	 * @param String cpf: string contendo o cpf
	 * @return true se o primeiro digito do cpf for valido
	 * @return false se o primeiro digito do cpf for invalido
	 */
	private static boolean primeiroDigitoCpf(String cpf){

		int soma = 0;
		int restoDivisao;
		int resultado;

		/*
		 * Pega o primeiro digito do cpf e multiplica por 10, o segundo
		 * por 9, e assim por diante.
		 * Soma o resultado de todas as multiplicacoes e guarda em soma
		 */
		for(int j = 0; j < 9; j++){

			int digito = Integer.parseInt(cpf.substring(j, j+1));

			soma += digito * (10-j);

		}

		restoDivisao = soma % 11;

		if(restoDivisao < 2){

			resultado = 0;

		}else{

			resultado = 11 - restoDivisao;

		}

		/*
		 * Verifica se o digito 10 (primeiro digito verificador) da string cpf
		 * e igual a resultado
		 */
		if(Integer.parseInt(cpf.substring(9,10)) == resultado){

			return true;

		}else{

			return false;

		}
	}//primeiroDigitoCpf(String cpf)

	/**
	 * 
	 * Esse metodo e usado pela funcao validaCpf para verificar
	 * se um cpf e valido,  o metodo e static pois e usado pelo 
	 * metodo validarCpf()
	 * 
	 * @param String cpf: string contendo o cpf
	 * @return true se o segundo digito do cpf for valido
	 * @return false se o segundo digito do cpf for invalido
	 */
	private static boolean segundoDigitoCpf(String cpf){

		int soma = 0;
		int restoDivisao;
		int resultado;

		/*
		 * Pega o primeiro digito do cpf e multiplica por 11, o segundo
		 * por 10, e assim por diante.
		 * Soma o resultado de todas as multiplicacoes e guarda em soma
		 */
		for(int j = 0; j < 10; j++){

			int digito = Integer.parseInt(cpf.substring(j,j+1));

			soma += digito * (11-j);

		}

		restoDivisao = soma%11;

		if(restoDivisao < 2){

			resultado=0;

		}else{

			resultado = 11-restoDivisao;

		}

		/*
		 * Verifica se o digito 11 (segundo digito verificador) da string cpf
		 * e igual a resultado
		 */
		if(Integer.parseInt(cpf.substring(10,11)) == resultado){

			return true;

		}else{

			return false;

		}
	}//segundoDigitoCpf(String cpf)


	/**
	 * 
	 * Esse metodo e usado pela funcao validaCnpj para verificar
	 * se um cnpj e valido, o metodo e static pois e usado pelo 
	 * metodo validarCnpj()
	 * 
	 * @param String cnpg: string contendo o cnpj
	 * @return true se o primeiro digito do cnpj for valido
	 * @return false se o primeiro digito do cnpj for invalido
	 */
	private static boolean primeiroDigitoCnpj(String cnpj){

		int[] multiplicador={5,4,3,2,9,8,7,6,5,4,3,2};
		int soma = 0;
		int restoDivisao;
		int resultado;


		for(int j = 0; j < 12; j++){

			int digito = Integer.parseInt(cnpj.substring(j, j+1));

			soma += digito * multiplicador[j];

		}

		restoDivisao = soma%11;

		if(restoDivisao < 2){

			resultado = 0;

		}else{

			resultado= 11 - restoDivisao;

		}

		if(Integer.parseInt(cnpj.substring(12,13)) == resultado){

			return true;

		}else{

			return false;

		}
	}//primeiroDigitoCnpj(String cnpj)

	/**
	 * 
	 * Esse metodo e usado pela funcao validaCnpj para verificar
	 * se um cnpj e valido,  o metodo e static pois e usado pelo 
	 * metodo validarCnpj()
	 * 
	 * @param String cnpj: string contendo o cnpj
	 * @return true se o segundo digito verificador do cnpj for valido
	 * @return false se o segundo digito do cnpj for invalido
	 */
	private static boolean segundoDigitoCnpj(String cnpj){

		int[] multiplicador={6,5,4,3,2,9,8,7,6,5,4,3,2};
		int soma = 0;
		int restoDivisao;
		int resultado;


		for(int j = 0; j < 13; j++){

			int digito = Integer.parseInt(cnpj.substring(j,j+1));

			soma += digito * multiplicador[j];

		}


		restoDivisao = soma%11;

		if(restoDivisao < 2){

			resultado = 0;

		}else{

			resultado= 11 - restoDivisao;

		}

		if(Integer.parseInt(cnpj.substring(13,14)) == resultado){

			return true;

		}else{

			return false;

		}
	}//segundoDigitoCnpj(String cnpj)

	/*
	 * Metodos Get e Set
	 */
	
	
	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public void setTelefone(String telefone) {
		this.telefone = telefone;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public void setEndereco(String endereco) {
		this.endereco = endereco;
	}

	public String getTelefone() {
		return telefone;
	}

	public String getEmail() {
		return email;
	}

	public String getEndereco() {
		return endereco;
	}

}//Pessoa
